home *** CD-ROM | disk | FTP | other *** search
/ Micromanía 92 / CDMM92_1.ISO / SOF 2 SDK / sof2sdk-101.msi / _92D6AC311BB48EBA344BBABC89DA6AB0 / _D28699A899684100BB8C4954A90C0EA1 < prev    next >
Encoding:
Text File  |  2002-06-20  |  33.5 KB  |  1,457 lines

  1. // Copyright (C) 2001-2002 Raven Software.
  2. //
  3. // q_math.c -- stateless support routines that are included in each code module
  4. #include "q_shared.h"
  5.  
  6.  
  7. vec3_t    vec3_origin =  {0.0f,0.0f,0.0f};
  8. vec3_t    vec3_identity = {1.0f, 1.0f, 1.0f};
  9. vec3_t    axisDefault[3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
  10.  
  11.  
  12. vec4_t        colorBlack    = {0, 0, 0, 1};
  13. vec4_t        colorRed    = {1, 0, 0, 1};
  14. vec4_t        colorGreen    = {169.0f/255.0f, 194.0f/255.0f, 116.0f/255.0f, 1.0}; // {0, 1, 0, 1};
  15. vec4_t        colorBlue    = {0, 0, 1, 1};
  16. vec4_t        colorYellow    = {1, 1, 0, 1};
  17. vec4_t        colorMagenta= {1, 0, 1, 1};
  18. vec4_t        colorCyan    = {0, 1, 1, 1};
  19. vec4_t        colorWhite    = {1, 1, 1, 1};
  20. vec4_t        colorLtGrey    = {0.75, 0.75, 0.75, 1};
  21. vec4_t        colorMdGrey    = {0.5, 0.5, 0.5, 1};
  22. vec4_t        colorDkGrey    = {0.25, 0.25, 0.25, 1};
  23.  
  24. vec4_t        colorLtBlue    = {0.367f, 0.261f, 0.722f, 1};
  25. vec4_t        colorDkBlue    = {0.199f, 0.0f,   0.398f, 1};
  26.  
  27. vec4_t    g_color_table[8] =
  28.     {
  29.     {0.0, 0.0, 0.0, 1.0},        // Black
  30. //    {1.0, 0.0, 0.0, 1.0},        // Red
  31.     {1.0, 0.1, 0.1, 1.0},        // Red
  32. //    {0.0, 1.0, 0.0, 1.0},        // Green
  33.     {169.0f/255.0f, 194.0f/255.0f, 116.0f/255.0f, 1.0},        // Green
  34.     {1.0, 1.0, 0.0, 1.0},        // Yellow
  35. //    {0.0, 0.0, 1.0, 1.0},        // Blue
  36.     {0.3, 0.3, 1.0, 1.0},        // Blue
  37.     {0.0, 1.0, 1.0, 1.0},        // Cyan
  38.     {1.0, 0.0, 1.0, 1.0},        // Magenta
  39.     {1.0, 1.0, 1.0, 1.0},        // White
  40.     };
  41.  
  42.  
  43. vec3_t    bytedirs[NUMVERTEXNORMALS] =
  44. {
  45. {-0.525731f, 0.000000f, 0.850651f}, {-0.442863f, 0.238856f, 0.864188f}, 
  46. {-0.295242f, 0.000000f, 0.955423f}, {-0.309017f, 0.500000f, 0.809017f}, 
  47. {-0.162460f, 0.262866f, 0.951056f}, {0.000000f, 0.000000f, 1.000000f}, 
  48. {0.000000f, 0.850651f, 0.525731f}, {-0.147621f, 0.716567f, 0.681718f}, 
  49. {0.147621f, 0.716567f, 0.681718f}, {0.000000f, 0.525731f, 0.850651f}, 
  50. {0.309017f, 0.500000f, 0.809017f}, {0.525731f, 0.000000f, 0.850651f}, 
  51. {0.295242f, 0.000000f, 0.955423f}, {0.442863f, 0.238856f, 0.864188f}, 
  52. {0.162460f, 0.262866f, 0.951056f}, {-0.681718f, 0.147621f, 0.716567f}, 
  53. {-0.809017f, 0.309017f, 0.500000f},{-0.587785f, 0.425325f, 0.688191f}, 
  54. {-0.850651f, 0.525731f, 0.000000f},{-0.864188f, 0.442863f, 0.238856f}, 
  55. {-0.716567f, 0.681718f, 0.147621f},{-0.688191f, 0.587785f, 0.425325f}, 
  56. {-0.500000f, 0.809017f, 0.309017f}, {-0.238856f, 0.864188f, 0.442863f}, 
  57. {-0.425325f, 0.688191f, 0.587785f}, {-0.716567f, 0.681718f, -0.147621f}, 
  58. {-0.500000f, 0.809017f, -0.309017f}, {-0.525731f, 0.850651f, 0.000000f}, 
  59. {0.000000f, 0.850651f, -0.525731f}, {-0.238856f, 0.864188f, -0.442863f}, 
  60. {0.000000f, 0.955423f, -0.295242f}, {-0.262866f, 0.951056f, -0.162460f}, 
  61. {0.000000f, 1.000000f, 0.000000f}, {0.000000f, 0.955423f, 0.295242f}, 
  62. {-0.262866f, 0.951056f, 0.162460f}, {0.238856f, 0.864188f, 0.442863f}, 
  63. {0.262866f, 0.951056f, 0.162460f}, {0.500000f, 0.809017f, 0.309017f}, 
  64. {0.238856f, 0.864188f, -0.442863f},{0.262866f, 0.951056f, -0.162460f}, 
  65. {0.500000f, 0.809017f, -0.309017f},{0.850651f, 0.525731f, 0.000000f}, 
  66. {0.716567f, 0.681718f, 0.147621f}, {0.716567f, 0.681718f, -0.147621f}, 
  67. {0.525731f, 0.850651f, 0.000000f}, {0.425325f, 0.688191f, 0.587785f}, 
  68. {0.864188f, 0.442863f, 0.238856f}, {0.688191f, 0.587785f, 0.425325f}, 
  69. {0.809017f, 0.309017f, 0.500000f}, {0.681718f, 0.147621f, 0.716567f}, 
  70. {0.587785f, 0.425325f, 0.688191f}, {0.955423f, 0.295242f, 0.000000f}, 
  71. {1.000000f, 0.000000f, 0.000000f}, {0.951056f, 0.162460f, 0.262866f}, 
  72. {0.850651f, -0.525731f, 0.000000f},{0.955423f, -0.295242f, 0.000000f}, 
  73. {0.864188f, -0.442863f, 0.238856f}, {0.951056f, -0.162460f, 0.262866f}, 
  74. {0.809017f, -0.309017f, 0.500000f}, {0.681718f, -0.147621f, 0.716567f}, 
  75. {0.850651f, 0.000000f, 0.525731f}, {0.864188f, 0.442863f, -0.238856f}, 
  76. {0.809017f, 0.309017f, -0.500000f}, {0.951056f, 0.162460f, -0.262866f}, 
  77. {0.525731f, 0.000000f, -0.850651f}, {0.681718f, 0.147621f, -0.716567f}, 
  78. {0.681718f, -0.147621f, -0.716567f},{0.850651f, 0.000000f, -0.525731f}, 
  79. {0.809017f, -0.309017f, -0.500000f}, {0.864188f, -0.442863f, -0.238856f}, 
  80. {0.951056f, -0.162460f, -0.262866f}, {0.147621f, 0.716567f, -0.681718f}, 
  81. {0.309017f, 0.500000f, -0.809017f}, {0.425325f, 0.688191f, -0.587785f}, 
  82. {0.442863f, 0.238856f, -0.864188f}, {0.587785f, 0.425325f, -0.688191f}, 
  83. {0.688191f, 0.587785f, -0.425325f}, {-0.147621f, 0.716567f, -0.681718f}, 
  84. {-0.309017f, 0.500000f, -0.809017f}, {0.000000f, 0.525731f, -0.850651f}, 
  85. {-0.525731f, 0.000000f, -0.850651f}, {-0.442863f, 0.238856f, -0.864188f}, 
  86. {-0.295242f, 0.000000f, -0.955423f}, {-0.162460f, 0.262866f, -0.951056f}, 
  87. {0.000000f, 0.000000f, -1.000000f}, {0.295242f, 0.000000f, -0.955423f}, 
  88. {0.162460f, 0.262866f, -0.951056f}, {-0.442863f, -0.238856f, -0.864188f}, 
  89. {-0.309017f, -0.500000f, -0.809017f}, {-0.162460f, -0.262866f, -0.951056f}, 
  90. {0.000000f, -0.850651f, -0.525731f}, {-0.147621f, -0.716567f, -0.681718f}, 
  91. {0.147621f, -0.716567f, -0.681718f}, {0.000000f, -0.525731f, -0.850651f}, 
  92. {0.309017f, -0.500000f, -0.809017f}, {0.442863f, -0.238856f, -0.864188f}, 
  93. {0.162460f, -0.262866f, -0.951056f}, {0.238856f, -0.864188f, -0.442863f}, 
  94. {0.500000f, -0.809017f, -0.309017f}, {0.425325f, -0.688191f, -0.587785f}, 
  95. {0.716567f, -0.681718f, -0.147621f}, {0.688191f, -0.587785f, -0.425325f}, 
  96. {0.587785f, -0.425325f, -0.688191f}, {0.000000f, -0.955423f, -0.295242f}, 
  97. {0.000000f, -1.000000f, 0.000000f}, {0.262866f, -0.951056f, -0.162460f}, 
  98. {0.000000f, -0.850651f, 0.525731f}, {0.000000f, -0.955423f, 0.295242f}, 
  99. {0.238856f, -0.864188f, 0.442863f}, {0.262866f, -0.951056f, 0.162460f}, 
  100. {0.500000f, -0.809017f, 0.309017f}, {0.716567f, -0.681718f, 0.147621f}, 
  101. {0.525731f, -0.850651f, 0.000000f}, {-0.238856f, -0.864188f, -0.442863f}, 
  102. {-0.500000f, -0.809017f, -0.309017f}, {-0.262866f, -0.951056f, -0.162460f}, 
  103. {-0.850651f, -0.525731f, 0.000000f}, {-0.716567f, -0.681718f, -0.147621f}, 
  104. {-0.716567f, -0.681718f, 0.147621f}, {-0.525731f, -0.850651f, 0.000000f}, 
  105. {-0.500000f, -0.809017f, 0.309017f}, {-0.238856f, -0.864188f, 0.442863f}, 
  106. {-0.262866f, -0.951056f, 0.162460f}, {-0.864188f, -0.442863f, 0.238856f}, 
  107. {-0.809017f, -0.309017f, 0.500000f}, {-0.688191f, -0.587785f, 0.425325f}, 
  108. {-0.681718f, -0.147621f, 0.716567f}, {-0.442863f, -0.238856f, 0.864188f}, 
  109. {-0.587785f, -0.425325f, 0.688191f}, {-0.309017f, -0.500000f, 0.809017f}, 
  110. {-0.147621f, -0.716567f, 0.681718f}, {-0.425325f, -0.688191f, 0.587785f}, 
  111. {-0.162460f, -0.262866f, 0.951056f}, {0.442863f, -0.238856f, 0.864188f}, 
  112. {0.162460f, -0.262866f, 0.951056f}, {0.309017f, -0.500000f, 0.809017f}, 
  113. {0.147621f, -0.716567f, 0.681718f}, {0.000000f, -0.525731f, 0.850651f}, 
  114. {0.425325f, -0.688191f, 0.587785f}, {0.587785f, -0.425325f, 0.688191f}, 
  115. {0.688191f, -0.587785f, 0.425325f}, {-0.955423f, 0.295242f, 0.000000f}, 
  116. {-0.951056f, 0.162460f, 0.262866f}, {-1.000000f, 0.000000f, 0.000000f}, 
  117. {-0.850651f, 0.000000f, 0.525731f}, {-0.955423f, -0.295242f, 0.000000f}, 
  118. {-0.951056f, -0.162460f, 0.262866f}, {-0.864188f, 0.442863f, -0.238856f}, 
  119. {-0.951056f, 0.162460f, -0.262866f}, {-0.809017f, 0.309017f, -0.500000f}, 
  120. {-0.864188f, -0.442863f, -0.238856f}, {-0.951056f, -0.162460f, -0.262866f}, 
  121. {-0.809017f, -0.309017f, -0.500000f}, {-0.681718f, 0.147621f, -0.716567f}, 
  122. {-0.681718f, -0.147621f, -0.716567f}, {-0.850651f, 0.000000f, -0.525731f}, 
  123. {-0.688191f, 0.587785f, -0.425325f}, {-0.587785f, 0.425325f, -0.688191f}, 
  124. {-0.425325f, 0.688191f, -0.587785f}, {-0.425325f, -0.688191f, -0.587785f}, 
  125. {-0.587785f, -0.425325f, -0.688191f}, {-0.688191f, -0.587785f, -0.425325f}
  126. };
  127.  
  128. //==============================================================
  129.  
  130. int        Q_rand( int *seed ) {
  131.     *seed = (69069 * *seed + 1);
  132.     return *seed;
  133. }
  134.  
  135. float    Q_random( int *seed ) {
  136.     return ( Q_rand( seed ) & 0xffff ) / (float)0x10000;
  137. }
  138.  
  139. float    Q_crandom( int *seed ) {
  140.     return 2.0 * ( Q_random( seed ) - 0.5 );
  141. }
  142.  
  143. #ifdef __LCC__
  144.  
  145. int VectorCompare( const vec3_t v1, const vec3_t v2 ) {
  146.     if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) {
  147.         return 0;
  148.     }            
  149.     return 1;
  150. }
  151.  
  152. vec_t VectorLength( const vec3_t v ) {
  153.     return (vec_t)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  154. }
  155.  
  156. vec_t VectorLengthSquared( const vec3_t v ) {
  157.     return (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  158. }
  159.  
  160. vec_t Distance( const vec3_t p1, const vec3_t p2 ) {
  161.     vec3_t    v;
  162.  
  163.     VectorSubtract (p2, p1, v);
  164.     return VectorLength( v );
  165. }
  166.  
  167. vec_t DistanceSquared( const vec3_t p1, const vec3_t p2 ) {
  168.     vec3_t    v;
  169.  
  170.     VectorSubtract (p2, p1, v);
  171.     return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  172. }
  173.  
  174. // fast vector normalize routine that does not check to make sure
  175. // that length != 0, nor does it return length, uses rsqrt approximation
  176. void VectorNormalizeFast( vec3_t v )
  177. {
  178.     float ilength;
  179.  
  180.     ilength = Q_rsqrt( DotProduct( v, v ) );
  181.  
  182.     v[0] *= ilength;
  183.     v[1] *= ilength;
  184.     v[2] *= ilength;
  185. }
  186.  
  187. void VectorInverse( vec3_t v ){
  188.     v[0] = -v[0];
  189.     v[1] = -v[1];
  190.     v[2] = -v[2];
  191. }
  192.  
  193. void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) {
  194.     cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
  195.     cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
  196.     cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
  197. }
  198. #endif
  199.  
  200. //=======================================================
  201.  
  202. signed char ClampChar( int i ) {
  203.     if ( i < -128 ) {
  204.         return -128;
  205.     }
  206.     if ( i > 127 ) {
  207.         return 127;
  208.     }
  209.     return i;
  210. }
  211.  
  212. signed short ClampShort( int i ) {
  213.     if ( i < -32768 ) {
  214.         return -32768;
  215.     }
  216.     if ( i > 0x7fff ) {
  217.         return 0x7fff;
  218.     }
  219.     return i;
  220. }
  221.  
  222.  
  223. // this isn't a real cheap function to call!
  224. int DirToByte( vec3_t dir ) {
  225.     int        i, best;
  226.     float    d, bestd;
  227.  
  228.     if ( !dir ) {
  229.         return 0;
  230.     }
  231.  
  232.     bestd = 0;
  233.     best = 0;
  234.     for (i=0 ; i<NUMVERTEXNORMALS ; i++)
  235.     {
  236.         d = DotProduct (dir, bytedirs[i]);
  237.         if (d > bestd)
  238.         {
  239.             bestd = d;
  240.             best = i;
  241.         }
  242.     }
  243.  
  244.     return best;
  245. }
  246.  
  247. void ByteToDir( int b, vec3_t dir ) {
  248.     if ( b < 0 || b >= NUMVERTEXNORMALS ) {
  249.         VectorCopy( vec3_origin, dir );
  250.         return;
  251.     }
  252.     VectorCopy (bytedirs[b], dir);
  253. }
  254.  
  255.  
  256. unsigned ColorBytes3 (float r, float g, float b) {
  257.     unsigned    i;
  258.  
  259.     ( (byte *)&i )[0] = r * 255;
  260.     ( (byte *)&i )[1] = g * 255;
  261.     ( (byte *)&i )[2] = b * 255;
  262.  
  263.     return i;
  264. }
  265.  
  266. unsigned ColorBytes4 (float r, float g, float b, float a) {
  267.     unsigned    i;
  268.  
  269.     ( (byte *)&i )[0] = r * 255;
  270.     ( (byte *)&i )[1] = g * 255;
  271.     ( (byte *)&i )[2] = b * 255;
  272.     ( (byte *)&i )[3] = a * 255;
  273.  
  274.     return i;
  275. }
  276.  
  277. float NormalizeColor( const vec3_t in, vec3_t out ) {
  278.     float    max;
  279.     
  280.     max = in[0];
  281.     if ( in[1] > max ) {
  282.         max = in[1];
  283.     }
  284.     if ( in[2] > max ) {
  285.         max = in[2];
  286.     }
  287.  
  288.     if ( !max ) {
  289.         VectorClear( out );
  290.     } else {
  291.         out[0] = in[0] / max;
  292.         out[1] = in[1] / max;
  293.         out[2] = in[2] / max;
  294.     }
  295.     return max;
  296. }
  297.  
  298.  
  299. /*
  300. =====================
  301. PlaneFromPoints
  302.  
  303. Returns false if the triangle is degenrate.
  304. The normal will point out of the clock for clockwise ordered points
  305. =====================
  306. */
  307. qboolean PlaneFromPoints( vec4_t plane, const vec3_t a, const vec3_t b, const vec3_t c ) {
  308.     vec3_t    d1, d2;
  309.  
  310.     VectorSubtract( b, a, d1 );
  311.     VectorSubtract( c, a, d2 );
  312.     CrossProduct( d2, d1, plane );
  313.     if ( VectorNormalize( plane ) == 0 ) {
  314.         return qfalse;
  315.     }
  316.  
  317.     plane[3] = DotProduct( a, plane );
  318.     return qtrue;
  319. }
  320.  
  321. /*
  322. ===============
  323. RotatePointAroundVector
  324.  
  325. This is not implemented very well...
  326. ===============
  327. */
  328. void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
  329.                              float degrees ) {
  330.     float    m[3][3];
  331.     float    im[3][3];
  332.     float    zrot[3][3];
  333.     float    tmpmat[3][3];
  334.     float    rot[3][3];
  335.     int    i;
  336.     vec3_t vr, vup, vf;
  337.     float    rad;
  338.  
  339.     vf[0] = dir[0];
  340.     vf[1] = dir[1];
  341.     vf[2] = dir[2];
  342.  
  343.     PerpendicularVector( vr, dir );
  344.     CrossProduct( vr, vf, vup );
  345.  
  346.     m[0][0] = vr[0];
  347.     m[1][0] = vr[1];
  348.     m[2][0] = vr[2];
  349.  
  350.     m[0][1] = vup[0];
  351.     m[1][1] = vup[1];
  352.     m[2][1] = vup[2];
  353.  
  354.     m[0][2] = vf[0];
  355.     m[1][2] = vf[1];
  356.     m[2][2] = vf[2];
  357.  
  358.     memcpy( im, m, sizeof( im ) );
  359.  
  360.     im[0][1] = m[1][0];
  361.     im[0][2] = m[2][0];
  362.     im[1][0] = m[0][1];
  363.     im[1][2] = m[2][1];
  364.     im[2][0] = m[0][2];
  365.     im[2][1] = m[1][2];
  366.  
  367.     memset( zrot, 0, sizeof( zrot ) );
  368.     zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;
  369.  
  370.     rad = DEG2RAD( degrees );
  371.     zrot[0][0] = cos( rad );
  372.     zrot[0][1] = sin( rad );
  373.     zrot[1][0] = -sin( rad );
  374.     zrot[1][1] = cos( rad );
  375.  
  376.     MatrixMultiply( m, zrot, tmpmat );
  377.     MatrixMultiply( tmpmat, im, rot );
  378.  
  379.     for ( i = 0; i < 3; i++ ) {
  380.         dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2];
  381.     }
  382. }
  383.  
  384. /*
  385. ===============
  386. RotateAroundDirection
  387. ===============
  388. */
  389. void RotateAroundDirection( vec3_t axis[3], float yaw ) {
  390.  
  391.     // create an arbitrary axis[1] 
  392.     PerpendicularVector( axis[1], axis[0] );
  393.  
  394.     // rotate it around axis[0] by yaw
  395.     if ( yaw ) {
  396.         vec3_t    temp;
  397.  
  398.         VectorCopy( axis[1], temp );
  399.         RotatePointAroundVector( axis[1], axis[0], temp, yaw );
  400.     }
  401.  
  402.     // cross to get axis[2]
  403.     CrossProduct( axis[0], axis[1], axis[2] );
  404. }
  405.  
  406.  
  407.  
  408. void vectoangles( const vec3_t value1, vec3_t angles ) {
  409.     float    forward;
  410.     float    yaw, pitch;
  411.     
  412.     if ( value1[1] == 0 && value1[0] == 0 ) {
  413.         yaw = 0;
  414.         if ( value1[2] > 0 ) {
  415.             pitch = 90;
  416.         }
  417.         else {
  418.             pitch = 270;
  419.         }
  420.     }
  421.     else {
  422.         if ( value1[0] ) {
  423.             yaw = ( atan2 ( value1[1], value1[0] ) * 180 / M_PI );
  424.         }
  425.         else if ( value1[1] > 0 ) {
  426.             yaw = 90;
  427.         }
  428.         else {
  429.             yaw = 270;
  430.         }
  431.         if ( yaw < 0 ) {
  432.             yaw += 360;
  433.         }
  434.  
  435.         forward = sqrt ( value1[0]*value1[0] + value1[1]*value1[1] );
  436.         pitch = ( atan2(value1[2], forward) * 180 / M_PI );
  437.         if ( pitch < 0 ) {
  438.             pitch += 360;
  439.         }
  440.     }
  441.  
  442.     angles[PITCH] = -pitch;
  443.     angles[YAW] = yaw;
  444.     angles[ROLL] = 0;
  445. }
  446.  
  447.  
  448. /*
  449. =================
  450. AnglesToAxis
  451. =================
  452. */
  453. void AnglesToAxis( const vec3_t angles, vec3_t axis[3] ) {
  454.     vec3_t    right;
  455.  
  456.     // angle vectors returns "right" instead of "y axis"
  457.     AngleVectors( angles, axis[0], right, axis[2] );
  458.     VectorSubtract( vec3_origin, right, axis[1] );
  459. }
  460.  
  461. void AxisClear( vec3_t axis[3] ) {
  462.     axis[0][0] = 1;
  463.     axis[0][1] = 0;
  464.     axis[0][2] = 0;
  465.     axis[1][0] = 0;
  466.     axis[1][1] = 1;
  467.     axis[1][2] = 0;
  468.     axis[2][0] = 0;
  469.     axis[2][1] = 0;
  470.     axis[2][2] = 1;
  471. }
  472.  
  473. void AxisCopy( vec3_t in[3], vec3_t out[3] ) {
  474.     VectorCopy( in[0], out[0] );
  475.     VectorCopy( in[1], out[1] );
  476.     VectorCopy( in[2], out[2] );
  477. }
  478.  
  479. void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
  480. {
  481.     float d;
  482.     vec3_t n;
  483.     float inv_denom;
  484.  
  485.     inv_denom =  DotProduct( normal, normal );
  486. #ifndef Q3_VM
  487.     assert( Q_fabs(inv_denom) != 0.0f ); // bk010122 - zero vectors get here
  488. #endif
  489.     inv_denom = 1.0f / inv_denom;
  490.  
  491.     d = DotProduct( normal, p ) * inv_denom;
  492.  
  493.     n[0] = normal[0] * inv_denom;
  494.     n[1] = normal[1] * inv_denom;
  495.     n[2] = normal[2] * inv_denom;
  496.  
  497.     dst[0] = p[0] - d * n[0];
  498.     dst[1] = p[1] - d * n[1];
  499.     dst[2] = p[2] - d * n[2];
  500. }
  501.  
  502. /*
  503. ================
  504. MakeNormalVectors
  505.  
  506. Given a normalized forward vector, create two
  507. other perpendicular vectors
  508. ================
  509. */
  510. void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up) {
  511.     float        d;
  512.  
  513.     // this rotate and negate guarantees a vector
  514.     // not colinear with the original
  515.     right[1] = -forward[0];
  516.     right[2] = forward[1];
  517.     right[0] = forward[2];
  518.  
  519.     d = DotProduct (right, forward);
  520.     VectorMA (right, -d, forward, right);
  521.     VectorNormalize (right);
  522.     CrossProduct (right, forward, up);
  523. }
  524.  
  525.  
  526. void VectorRotate( vec3_t in, vec3_t matrix[3], vec3_t out )
  527. {
  528.     out[0] = DotProduct( in, matrix[0] );
  529.     out[1] = DotProduct( in, matrix[1] );
  530.     out[2] = DotProduct( in, matrix[2] );
  531. }
  532.  
  533. //============================================================================
  534.  
  535. #if !idppc
  536. /*
  537. ** float q_rsqrt( float number )
  538. */
  539. float Q_rsqrt( float number )
  540. {
  541.     long i;
  542.     float x2, y;
  543.     const float threehalfs = 1.5F;
  544.  
  545.     x2 = number * 0.5F;
  546.     y  = number;
  547.     i  = * ( long * ) &y;                        // evil floating point bit level hacking
  548.     i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
  549.     y  = * ( float * ) &i;
  550.     y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
  551. //    y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
  552.  
  553. #ifndef Q3_VM
  554. #ifdef __linux__
  555.     assert( !isnan(y) ); // bk010122 - FPE?
  556. #endif
  557. #endif
  558.     return y;
  559. }
  560.  
  561. float Q_fabs( float f ) {
  562.     int tmp = * ( int * ) &f;
  563.     tmp &= 0x7FFFFFFF;
  564.     return * ( float * ) &tmp;
  565. }
  566. #endif
  567.  
  568. //============================================================
  569.  
  570. /*
  571. ===============
  572. LerpAngle
  573.  
  574. ===============
  575. */
  576. float LerpAngle (float from, float to, float frac) {
  577.     float    a;
  578.  
  579.     if ( to - from > 180 ) {
  580.         to -= 360;
  581.     }
  582.     if ( to - from < -180 ) {
  583.         to += 360;
  584.     }
  585.     a = from + frac * (to - from);
  586.  
  587.     return a;
  588. }
  589.  
  590. void LerpVector ( vec3_t from, vec3_t to, float lerp, vec3_t out )
  591. {
  592.     out[0] = from[0] + (to[0]-from[0]) * lerp;
  593.     out[1] = from[1] + (to[1]-from[1]) * lerp;
  594.     out[2] = from[2] + (to[2]-from[2]) * lerp;
  595. }
  596.  
  597. /*
  598. =================
  599. AngleSubtract
  600.  
  601. Always returns a value from -180 to 180
  602. =================
  603. */
  604. float    AngleSubtract( float a1, float a2 ) {
  605.     float    a;
  606.  
  607.     a = a1 - a2;
  608.     while ( a > 180 ) {
  609.         a -= 360;
  610.     }
  611.     while ( a < -180 ) {
  612.         a += 360;
  613.     }
  614.     return a;
  615. }
  616.  
  617.  
  618. void AnglesSubtract( vec3_t v1, vec3_t v2, vec3_t v3 ) {
  619.     v3[0] = AngleSubtract( v1[0], v2[0] );
  620.     v3[1] = AngleSubtract( v1[1], v2[1] );
  621.     v3[2] = AngleSubtract( v1[2], v2[2] );
  622. }
  623.  
  624.  
  625. float    AngleMod(float a) {
  626.     a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535);
  627.     return a;
  628. }
  629.  
  630.  
  631. /*
  632. =================
  633. AngleNormalize360
  634.  
  635. returns angle normalized to the range [0 <= angle < 360]
  636. =================
  637. */
  638. float AngleNormalize360 ( float angle ) {
  639.     return (360.0 / 65536) * ((int)(angle * (65536 / 360.0)) & 65535);
  640. }
  641.  
  642.  
  643. /*
  644. =================
  645. AngleNormalize180
  646.  
  647. returns angle normalized to the range [-180 < angle <= 180]
  648. =================
  649. */
  650. float AngleNormalize180 ( float angle ) {
  651.     angle = AngleNormalize360( angle );
  652.     if ( angle > 180.0 ) {
  653.         angle -= 360.0;
  654.     }
  655.     return angle;
  656. }
  657.  
  658.  
  659. /*
  660. =================
  661. AngleDelta
  662.  
  663. returns the normalized delta from angle1 to angle2
  664. =================
  665. */
  666. float AngleDelta ( float angle1, float angle2 ) {
  667.     return AngleNormalize180( angle1 - angle2 );
  668. }
  669.  
  670.  
  671. //============================================================
  672.  
  673.  
  674. /*
  675. =================
  676. SetPlaneSignbits
  677. =================
  678. */
  679. void SetPlaneSignbits (cplane_t *out) {
  680.     int    bits, j;
  681.  
  682.     // for fast box on planeside test
  683.     bits = 0;
  684.     for (j=0 ; j<3 ; j++) {
  685.         if (out->normal[j] < 0) {
  686.             bits |= 1<<j;
  687.         }
  688.     }
  689.     out->signbits = bits;
  690. }
  691.  
  692.  
  693. /*
  694. ==================
  695. BoxOnPlaneSide
  696.  
  697. Returns 1, 2, or 1 + 2
  698.  
  699. // this is the slow, general version
  700. int BoxOnPlaneSide2 (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
  701. {
  702.     int        i;
  703.     float    dist1, dist2;
  704.     int        sides;
  705.     vec3_t    corners[2];
  706.  
  707.     for (i=0 ; i<3 ; i++)
  708.     {
  709.         if (p->normal[i] < 0)
  710.         {
  711.             corners[0][i] = emins[i];
  712.             corners[1][i] = emaxs[i];
  713.         }
  714.         else
  715.         {
  716.             corners[1][i] = emins[i];
  717.             corners[0][i] = emaxs[i];
  718.         }
  719.     }
  720.     dist1 = DotProduct (p->normal, corners[0]) - p->dist;
  721.     dist2 = DotProduct (p->normal, corners[1]) - p->dist;
  722.     sides = 0;
  723.     if (dist1 >= 0)
  724.         sides = 1;
  725.     if (dist2 < 0)
  726.         sides |= 2;
  727.  
  728.     return sides;
  729. }
  730.  
  731. ==================
  732. */
  733. #if !( (defined __linux__ || __FreeBSD__) && (defined __i386__) && (!defined C_ONLY)) // rb010123
  734.  
  735. #if defined __LCC__ || defined C_ONLY || !id386
  736.  
  737. int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
  738. {
  739.     float    dist1, dist2;
  740.     int        sides;
  741.  
  742. // fast axial cases
  743.     if (p->type < 3)
  744.     {
  745.         if (p->dist <= emins[p->type])
  746.             return 1;
  747.         if (p->dist >= emaxs[p->type])
  748.             return 2;
  749.         return 3;
  750.     }
  751.  
  752. // general case
  753.     switch (p->signbits)
  754.     {
  755.     case 0:
  756.         dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  757.         dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  758.         break;
  759.     case 1:
  760.         dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  761.         dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  762.         break;
  763.     case 2:
  764.         dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  765.         dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  766.         break;
  767.     case 3:
  768.         dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  769.         dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  770.         break;
  771.     case 4:
  772.         dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  773.         dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  774.         break;
  775.     case 5:
  776.         dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
  777.         dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
  778.         break;
  779.     case 6:
  780.         dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  781.         dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  782.         break;
  783.     case 7:
  784.         dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
  785.         dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
  786.         break;
  787.     default:
  788.         dist1 = dist2 = 0;        // shut up compiler
  789.         break;
  790.     }
  791.  
  792.     sides = 0;
  793.     if (dist1 >= p->dist)
  794.         sides = 1;
  795.     if (dist2 < p->dist)
  796.         sides |= 2;
  797.  
  798.     return sides;
  799. }
  800. #else
  801. #pragma warning( disable: 4035 )
  802.  
  803. __declspec( naked ) int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p)
  804. {
  805.     static int bops_initialized;
  806.     static int Ljmptab[8];
  807.  
  808.     __asm {
  809.  
  810.         push ebx
  811.             
  812.         cmp bops_initialized, 1
  813.         je  initialized
  814.         mov bops_initialized, 1
  815.         
  816.         mov Ljmptab[0*4], offset Lcase0
  817.         mov Ljmptab[1*4], offset Lcase1
  818.         mov Ljmptab[2*4], offset Lcase2
  819.         mov Ljmptab[3*4], offset Lcase3
  820.         mov Ljmptab[4*4], offset Lcase4
  821.         mov Ljmptab[5*4], offset Lcase5
  822.         mov Ljmptab[6*4], offset Lcase6
  823.         mov Ljmptab[7*4], offset Lcase7
  824.             
  825. initialized:
  826.  
  827.         mov edx,dword ptr[4+12+esp]
  828.         mov ecx,dword ptr[4+4+esp]
  829.         xor eax,eax
  830.         mov ebx,dword ptr[4+8+esp]
  831.         mov al,byte ptr[17+edx]
  832.         cmp al,8
  833.         jge Lerror
  834.         fld dword ptr[0+edx]
  835.         fld st(0)
  836.         jmp dword ptr[Ljmptab+eax*4]
  837. Lcase0:
  838.         fmul dword ptr[ebx]
  839.         fld dword ptr[0+4+edx]
  840.         fxch st(2)
  841.         fmul dword ptr[ecx]
  842.         fxch st(2)
  843.         fld st(0)
  844.         fmul dword ptr[4+ebx]
  845.         fld dword ptr[0+8+edx]
  846.         fxch st(2)
  847.         fmul dword ptr[4+ecx]
  848.         fxch st(2)
  849.         fld st(0)
  850.         fmul dword ptr[8+ebx]
  851.         fxch st(5)
  852.         faddp st(3),st(0)
  853.         fmul dword ptr[8+ecx]
  854.         fxch st(1)
  855.         faddp st(3),st(0)
  856.         fxch st(3)
  857.         faddp st(2),st(0)
  858.         jmp LSetSides
  859. Lcase1:
  860.         fmul dword ptr[ecx]
  861.         fld dword ptr[0+4+edx]
  862.         fxch st(2)
  863.         fmul dword ptr[ebx]
  864.         fxch st(2)
  865.         fld st(0)
  866.         fmul dword ptr[4+ebx]
  867.         fld dword ptr[0+8+edx]
  868.         fxch st(2)
  869.         fmul dword ptr[4+ecx]
  870.         fxch st(2)
  871.         fld st(0)
  872.         fmul dword ptr[8+ebx]
  873.         fxch st(5)
  874.         faddp st(3),st(0)
  875.         fmul dword ptr[8+ecx]
  876.         fxch st(1)
  877.         faddp st(3),st(0)
  878.         fxch st(3)
  879.         faddp st(2),st(0)
  880.         jmp LSetSides
  881. Lcase2:
  882.         fmul dword ptr[ebx]
  883.         fld dword ptr[0+4+edx]
  884.         fxch st(2)
  885.         fmul dword ptr[ecx]
  886.         fxch st(2)
  887.         fld st(0)
  888.         fmul dword ptr[4+ecx]
  889.         fld dword ptr[0+8+edx]
  890.         fxch st(2)
  891.         fmul dword ptr[4+ebx]
  892.         fxch st(2)
  893.         fld st(0)
  894.         fmul dword ptr[8+ebx]
  895.         fxch st(5)
  896.         faddp st(3),st(0)
  897.         fmul dword ptr[8+ecx]
  898.         fxch st(1)
  899.         faddp st(3),st(0)
  900.         fxch st(3)
  901.         faddp st(2),st(0)
  902.         jmp LSetSides
  903. Lcase3:
  904.         fmul dword ptr[ecx]
  905.         fld dword ptr[0+4+edx]
  906.         fxch st(2)
  907.         fmul dword ptr[ebx]
  908.         fxch st(2)
  909.         fld st(0)
  910.         fmul dword ptr[4+ecx]
  911.         fld dword ptr[0+8+edx]
  912.         fxch st(2)
  913.         fmul dword ptr[4+ebx]
  914.         fxch st(2)
  915.         fld st(0)
  916.         fmul dword ptr[8+ebx]
  917.         fxch st(5)
  918.         faddp st(3),st(0)
  919.         fmul dword ptr[8+ecx]
  920.         fxch st(1)
  921.         faddp st(3),st(0)
  922.         fxch st(3)
  923.         faddp st(2),st(0)
  924.         jmp LSetSides
  925. Lcase4:
  926.         fmul dword ptr[ebx]
  927.         fld dword ptr[0+4+edx]
  928.         fxch st(2)
  929.         fmul dword ptr[ecx]
  930.         fxch st(2)
  931.         fld st(0)
  932.         fmul dword ptr[4+ebx]
  933.         fld dword ptr[0+8+edx]
  934.         fxch st(2)
  935.         fmul dword ptr[4+ecx]
  936.         fxch st(2)
  937.         fld st(0)
  938.         fmul dword ptr[8+ecx]
  939.         fxch st(5)
  940.         faddp st(3),st(0)
  941.         fmul dword ptr[8+ebx]
  942.         fxch st(1)
  943.         faddp st(3),st(0)
  944.         fxch st(3)
  945.         faddp st(2),st(0)
  946.         jmp LSetSides
  947. Lcase5:
  948.         fmul dword ptr[ecx]
  949.         fld dword ptr[0+4+edx]
  950.         fxch st(2)
  951.         fmul dword ptr[ebx]
  952.         fxch st(2)
  953.         fld st(0)
  954.         fmul dword ptr[4+ebx]
  955.         fld dword ptr[0+8+edx]
  956.         fxch st(2)
  957.         fmul dword ptr[4+ecx]
  958.         fxch st(2)
  959.         fld st(0)
  960.         fmul dword ptr[8+ecx]
  961.         fxch st(5)
  962.         faddp st(3),st(0)
  963.         fmul dword ptr[8+ebx]
  964.         fxch st(1)
  965.         faddp st(3),st(0)
  966.         fxch st(3)
  967.         faddp st(2),st(0)
  968.         jmp LSetSides
  969. Lcase6:
  970.         fmul dword ptr[ebx]
  971.         fld dword ptr[0+4+edx]
  972.         fxch st(2)
  973.         fmul dword ptr[ecx]
  974.         fxch st(2)
  975.         fld st(0)
  976.         fmul dword ptr[4+ecx]
  977.         fld dword ptr[0+8+edx]
  978.         fxch st(2)
  979.         fmul dword ptr[4+ebx]
  980.         fxch st(2)
  981.         fld st(0)
  982.         fmul dword ptr[8+ecx]
  983.         fxch st(5)
  984.         faddp st(3),st(0)
  985.         fmul dword ptr[8+ebx]
  986.         fxch st(1)
  987.         faddp st(3),st(0)
  988.         fxch st(3)
  989.         faddp st(2),st(0)
  990.         jmp LSetSides
  991. Lcase7:
  992.         fmul dword ptr[ecx]
  993.         fld dword ptr[0+4+edx]
  994.         fxch st(2)
  995.         fmul dword ptr[ebx]
  996.         fxch st(2)
  997.         fld st(0)
  998.         fmul dword ptr[4+ecx]
  999.         fld dword ptr[0+8+edx]
  1000.         fxch st(2)
  1001.         fmul dword ptr[4+ebx]
  1002.         fxch st(2)
  1003.         fld st(0)
  1004.         fmul dword ptr[8+ecx]
  1005.         fxch st(5)
  1006.         faddp st(3),st(0)
  1007.         fmul dword ptr[8+ebx]
  1008.         fxch st(1)
  1009.         faddp st(3),st(0)
  1010.         fxch st(3)
  1011.         faddp st(2),st(0)
  1012. LSetSides:
  1013.         faddp st(2),st(0)
  1014.         fcomp dword ptr[12+edx]
  1015.         xor ecx,ecx
  1016.         fnstsw ax
  1017.         fcomp dword ptr[12+edx]
  1018.         and ah,1
  1019.         xor ah,1
  1020.         add cl,ah
  1021.         fnstsw ax
  1022.         and ah,1
  1023.         add ah,ah
  1024.         add cl,ah
  1025.         pop ebx
  1026.         mov eax,ecx
  1027.         ret
  1028. Lerror:
  1029.         int 3
  1030.     }
  1031. }
  1032. #pragma warning( default: 4035 )
  1033.  
  1034. #endif
  1035. #endif
  1036.  
  1037. /*
  1038. =================
  1039. RadiusFromBounds
  1040. =================
  1041. */
  1042. float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ) {
  1043.     int        i;
  1044.     vec3_t    corner;
  1045.     float    a, b;
  1046.  
  1047.     for (i=0 ; i<3 ; i++) {
  1048.         a = fabs( mins[i] );
  1049.         b = fabs( maxs[i] );
  1050.         corner[i] = a > b ? a : b;
  1051.     }
  1052.  
  1053.     return VectorLength (corner);
  1054. }
  1055.  
  1056.  
  1057. void ClearBounds( vec3_t mins, vec3_t maxs ) {
  1058.     mins[0] = mins[1] = mins[2] = 99999;
  1059.     maxs[0] = maxs[1] = maxs[2] = -99999;
  1060. }
  1061.  
  1062. void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ) {
  1063.     if ( v[0] < mins[0] ) {
  1064.         mins[0] = v[0];
  1065.     }
  1066.     if ( v[0] > maxs[0]) {
  1067.         maxs[0] = v[0];
  1068.     }
  1069.  
  1070.     if ( v[1] < mins[1] ) {
  1071.         mins[1] = v[1];
  1072.     }
  1073.     if ( v[1] > maxs[1]) {
  1074.         maxs[1] = v[1];
  1075.     }
  1076.  
  1077.     if ( v[2] < mins[2] ) {
  1078.         mins[2] = v[2];
  1079.     }
  1080.     if ( v[2] > maxs[2]) {
  1081.         maxs[2] = v[2];
  1082.     }
  1083. }
  1084.  
  1085.  
  1086. vec_t VectorNormalize( vec3_t v ) {
  1087.     float    length, ilength;
  1088.  
  1089.     length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  1090.     length = sqrt (length);
  1091.  
  1092.     if ( length ) {
  1093.         ilength = 1/length;
  1094.         v[0] *= ilength;
  1095.         v[1] *= ilength;
  1096.         v[2] *= ilength;
  1097.     }
  1098.         
  1099.     return length;
  1100. }
  1101.  
  1102. vec_t VectorNormalize2( const vec3_t v, vec3_t out) {
  1103.     float    length, ilength;
  1104.  
  1105.     length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  1106.     length = sqrt (length);
  1107.  
  1108.     if (length)
  1109.     {
  1110. #ifndef Q3_VM // bk0101022 - FPE related
  1111. //      assert( ((Q_fabs(v[0])!=0.0f) || (Q_fabs(v[1])!=0.0f) || (Q_fabs(v[2])!=0.0f)) );
  1112. #endif
  1113.         ilength = 1/length;
  1114.         out[0] = v[0]*ilength;
  1115.         out[1] = v[1]*ilength;
  1116.         out[2] = v[2]*ilength;
  1117.     } else {
  1118. #ifndef Q3_VM // bk0101022 - FPE related
  1119. //      assert( ((Q_fabs(v[0])==0.0f) && (Q_fabs(v[1])==0.0f) && (Q_fabs(v[2])==0.0f)) );
  1120. #endif
  1121.         VectorClear( out );
  1122.     }
  1123.         
  1124.     return length;
  1125.  
  1126. }
  1127.  
  1128. void _VectorMA( const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc) {
  1129.     vecc[0] = veca[0] + scale*vecb[0];
  1130.     vecc[1] = veca[1] + scale*vecb[1];
  1131.     vecc[2] = veca[2] + scale*vecb[2];
  1132. }
  1133.  
  1134.  
  1135. vec_t _DotProduct( const vec3_t v1, const vec3_t v2 ) {
  1136.     return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
  1137. }
  1138.  
  1139. void _VectorSubtract( const vec3_t veca, const vec3_t vecb, vec3_t out ) {
  1140.     out[0] = veca[0]-vecb[0];
  1141.     out[1] = veca[1]-vecb[1];
  1142.     out[2] = veca[2]-vecb[2];
  1143. }
  1144.  
  1145. void _VectorAdd( const vec3_t veca, const vec3_t vecb, vec3_t out ) {
  1146.     out[0] = veca[0]+vecb[0];
  1147.     out[1] = veca[1]+vecb[1];
  1148.     out[2] = veca[2]+vecb[2];
  1149. }
  1150.  
  1151. void _VectorCopy( const vec3_t in, vec3_t out ) {
  1152.     out[0] = in[0];
  1153.     out[1] = in[1];
  1154.     out[2] = in[2];
  1155. }
  1156.  
  1157. void _VectorScale( const vec3_t in, vec_t scale, vec3_t out ) {
  1158.     out[0] = in[0]*scale;
  1159.     out[1] = in[1]*scale;
  1160.     out[2] = in[2]*scale;
  1161. }
  1162.  
  1163. void Vector4Scale( const vec4_t in, vec_t scale, vec4_t out ) {
  1164.     out[0] = in[0]*scale;
  1165.     out[1] = in[1]*scale;
  1166.     out[2] = in[2]*scale;
  1167.     out[3] = in[3]*scale;
  1168. }
  1169.  
  1170.  
  1171. int Q_log2( int val ) {
  1172.     int answer;
  1173.  
  1174.     answer = 0;
  1175.     while ( ( val>>=1 ) != 0 ) {
  1176.         answer++;
  1177.     }
  1178.     return answer;
  1179. }
  1180.  
  1181. /*
  1182. ================
  1183. Q_TestRaySphere
  1184.  
  1185. Tests to see if the given ray intersects the given sphere
  1186. ================
  1187. */
  1188. qboolean Q_TestRaySphere ( vec3_t origin, float radius, const vec3_t start, const vec3_t end )
  1189. {
  1190.     float    v;
  1191.     float    disc;
  1192.     vec3_t    temp;
  1193.     vec3_t    dir;
  1194.  
  1195.     VectorSubtract ( origin, start, temp );
  1196.     VectorSubtract ( end, start, dir );
  1197.     VectorNormalize ( dir );
  1198.  
  1199.     // Make sure the sphere isnt behind them
  1200.     v = DotProduct ( temp, dir );
  1201.     if ( v < 0 )
  1202.     {
  1203.         return qfalse;
  1204.     }
  1205.  
  1206.     // Determine if it hit the sphere or not
  1207.     disc = radius * radius - (DotProduct ( temp, temp ) - v * v );
  1208.     if ( disc < 0 )
  1209.     {
  1210.         return qfalse;
  1211.     }
  1212.  
  1213.     return qtrue;
  1214. }
  1215.  
  1216.  
  1217. /*
  1218. =================
  1219. PlaneTypeForNormal
  1220. =================
  1221. */
  1222. /*
  1223. int    PlaneTypeForNormal (vec3_t normal) {
  1224.     if ( normal[0] == 1.0 )
  1225.         return PLANE_X;
  1226.     if ( normal[1] == 1.0 )
  1227.         return PLANE_Y;
  1228.     if ( normal[2] == 1.0 )
  1229.         return PLANE_Z;
  1230.     
  1231.     return PLANE_NON_AXIAL;
  1232. }
  1233. */
  1234.  
  1235.  
  1236. /*
  1237. ================
  1238. MatrixMultiply
  1239. ================
  1240. */
  1241. void MatrixMultiply(float in1[3][3], float in2[3][3], float out[3][3]) {
  1242.     out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
  1243.                 in1[0][2] * in2[2][0];
  1244.     out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
  1245.                 in1[0][2] * in2[2][1];
  1246.     out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
  1247.                 in1[0][2] * in2[2][2];
  1248.     out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
  1249.                 in1[1][2] * in2[2][0];
  1250.     out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
  1251.                 in1[1][2] * in2[2][1];
  1252.     out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
  1253.                 in1[1][2] * in2[2][2];
  1254.     out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
  1255.                 in1[2][2] * in2[2][0];
  1256.     out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
  1257.                 in1[2][2] * in2[2][1];
  1258.     out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
  1259.                 in1[2][2] * in2[2][2];
  1260. }
  1261.  
  1262.  
  1263. void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) {
  1264.     float        angle;
  1265.     static float        sr, sp, sy, cr, cp, cy;
  1266.     // static to help MS compiler fp bugs
  1267.  
  1268.     angle = angles[YAW] * (M_PI*2 / 360);
  1269.     sy = sin(angle);
  1270.     cy = cos(angle);
  1271.     angle = angles[PITCH] * (M_PI*2 / 360);
  1272.     sp = sin(angle);
  1273.     cp = cos(angle);
  1274.     angle = angles[ROLL] * (M_PI*2 / 360);
  1275.     sr = sin(angle);
  1276.     cr = cos(angle);
  1277.  
  1278.     if (forward)
  1279.     {
  1280.         forward[0] = cp*cy;
  1281.         forward[1] = cp*sy;
  1282.         forward[2] = -sp;
  1283.     }
  1284.     if (right)
  1285.     {
  1286.         right[0] = (-1*sr*sp*cy+-1*cr*-sy);
  1287.         right[1] = (-1*sr*sp*sy+-1*cr*cy);
  1288.         right[2] = -1*sr*cp;
  1289.     }
  1290.     if (up)
  1291.     {
  1292.         up[0] = (cr*sp*cy+-sr*-sy);
  1293.         up[1] = (cr*sp*sy+-sr*cy);
  1294.         up[2] = cr*cp;
  1295.     }
  1296. }
  1297.  
  1298. /*
  1299. ** assumes "src" is normalized
  1300. */
  1301. void PerpendicularVector( vec3_t dst, const vec3_t src )
  1302. {
  1303.     int    pos;
  1304.     int i;
  1305.     float minelem = 1.0F;
  1306.     vec3_t tempvec;
  1307.  
  1308.     /*
  1309.     ** find the smallest magnitude axially aligned vector
  1310.     */
  1311.     for ( pos = 0, i = 0; i < 3; i++ )
  1312.     {
  1313.         if ( fabs( src[i] ) < minelem )
  1314.         {
  1315.             pos = i;
  1316.             minelem = fabs( src[i] );
  1317.         }
  1318.     }
  1319.     tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
  1320.     tempvec[pos] = 1.0F;
  1321.  
  1322.     /*
  1323.     ** project the point onto the plane defined by src
  1324.     */
  1325.     ProjectPointOnPlane( dst, tempvec, src );
  1326.  
  1327.     /*
  1328.     ** normalize the result
  1329.     */
  1330.     VectorNormalize( dst );
  1331. }
  1332.  
  1333. /*
  1334. ** NormalToLatLong
  1335. **
  1336. ** We use two byte encoded normals in some space critical applications.
  1337. ** Lat = 0 at (1,0,0) to 360 (-1,0,0), encoded in 8-bit sine table format
  1338. ** Lng = 0 at (0,0,1) to 180 (0,0,-1), encoded in 8-bit sine table format
  1339. **
  1340. */
  1341. void NormalToLatLong( const vec3_t normal, byte bytes[2] )
  1342. {
  1343.     // check for singularities
  1344.     if (!normal[0] && !normal[1])
  1345.     {
  1346.         if ( normal[2] > 0.0f )
  1347.         {
  1348.             bytes[0] = 0;
  1349.             bytes[1] = 0;        // lat = 0, long = 0
  1350.         }
  1351.         else
  1352.         {
  1353.             bytes[0] = 128;
  1354.             bytes[1] = 0;        // lat = 0, long = 128
  1355.         }
  1356.     }
  1357.     else
  1358.     {
  1359.         int    a, b;
  1360.  
  1361.         a = (int)(RAD2DEG( (vec_t)atan2( normal[1], normal[0] ) ) * (255.0f / 360.0f ));
  1362.         a &= 0xff;
  1363.  
  1364.         b = (int)(RAD2DEG( (vec_t)acos( normal[2] ) ) * ( 255.0f / 360.0f ));
  1365.         b &= 0xff;
  1366.  
  1367.         bytes[0] = b;    // longitude
  1368.         bytes[1] = a;    // lattitude
  1369.     }
  1370. }
  1371.  
  1372. // This is the VC libc version of rand() without multiple seeds per thread or 12 levels
  1373. // of subroutine calls.
  1374. // Both calls have been designed to minimise the inherent number of float <--> int 
  1375. // conversions and the additional math required to get the desired value.
  1376. // eg the typical tint = (rand() * 255) / 32768
  1377. // becomes tint = irand(0, 255)
  1378.  
  1379. static unsigned long    holdrand = 0x89abcdef;
  1380.  
  1381. #ifdef __cplusplus
  1382.     int        randIndex;
  1383.     float    randTable[RAND_TABLE_SIZE];
  1384. #endif
  1385.  
  1386. void Rand_Init(int seed)
  1387. {
  1388. #ifdef __cplusplus
  1389.     int    i;
  1390. #endif
  1391.  
  1392.     holdrand = seed;
  1393.  
  1394. #ifdef __cplusplus
  1395.     for(i = 0; i < RAND_TABLE_SIZE; i++)
  1396.     {
  1397.         randTable[i] = flrand(0.0f, 1.0f);
  1398.     }
  1399. #endif
  1400. }
  1401.  
  1402. // Returns a float min <= x < max (exclusive; will get max - 0.00001; but never max)
  1403.  
  1404. float flrand(float min, float max)
  1405. {
  1406.     float    result;
  1407.  
  1408.     assert((max - min) < 32768);
  1409.  
  1410.     holdrand = (holdrand * 214013L) + 2531011L;
  1411.     result = (float)(holdrand >> 17);                        // 0 - 32767 range
  1412.     result = ((result * (max - min)) / 32768.0F) + min;
  1413.  
  1414.     return(result);
  1415. }
  1416.  
  1417. // Returns an integer min <= x <= max (ie inclusive)
  1418.  
  1419. int irand(int min, int max)
  1420. {
  1421.     int        result;
  1422.  
  1423.     assert((max - min) < 32768);
  1424.  
  1425.     max++;
  1426.     holdrand = (holdrand * 214013L) + 2531011L;
  1427.     result = holdrand >> 17;
  1428.     result = ((result * (max - min)) >> 15) + min;
  1429.     return(result);
  1430. }
  1431.  
  1432. float powf ( float x, int y )
  1433. {
  1434.     float r = x;
  1435.     for ( y--; y>0; y-- )
  1436.         r = r * r;
  1437.     return r;
  1438. }
  1439.  
  1440. #ifdef Q3_VM 
  1441.  
  1442. double fmod( double x, double y )
  1443. {
  1444.     int        result;
  1445.  
  1446.     if (y == 0.0)
  1447.     {
  1448.         return 0.0;
  1449.     }
  1450.  
  1451.     result = x / y;
  1452.  
  1453.     return x - (result * y);
  1454. }
  1455.  
  1456. #endif // Q3_VM
  1457.